/*
 * Testing the Mongo code from their site:
 * http://www.mongodb.org/display/DOCS/Java+Tutorial#JavaTutorial-MakingAConnection
 * 
 * Windows MongoDB quickstart tutorial:
 * http://www.mongodb.org/display/DOCS/Quickstart+Windows
 * 
 */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Set;

import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.MongoException;

public class parseToDB{

	private static int SUCCESS = 1, FAILED = -1;
	private int port = -1;
	private Mongo m;
	private String hostname;
	private String DBname;
	private static String delims = ",";
	private static String[] tokens;
	private static String line;
	private static DB db;
	/*
	 * Constructors
	 * 
	 */

	// parseToDB constructor for connections made with just the database name.
	// Warning message is sent that Mongo will assume localhost.
	public parseToDB(String DBname) 
	{
		try {
			m = new Mongo();
			this.hostname = "localhost";
			this.DBname = DBname;
			db = m.getDB(DBname);
		} catch (UnknownHostException e) {
			System.out.println("UnknownHostException error encountered. " +
			"Host attempted: localhost.");
			return;

		} catch (MongoException e) {
			System.out.println("MongoException error encountered. " +
			"Host attempted: localhost.");
			return;
		}
		System.out.println("Warning: Hostname has not been supplied - Mongo will " +
		"assume local host");
		System.out.println("Connetion established to: localhost. Database: " + 
				DBname);
	}
	// parseToDB constructor for connections made with the hostname AND database
	// name supplied.
	public parseToDB(String hostname, String DBname) 
	{
		try {
			m = new Mongo(hostname);
			this.hostname = hostname;
			this.DBname = DBname;
			db = m.getDB(DBname);
		} catch (UnknownHostException e) {
			System.out.println("UnknownHostException error encountered. " +
					"Host attempted: " + hostname + ". Database: " + DBname);
			return;
		} catch (MongoException e) {
			System.out.println("MongoException error encountered. " +
					"Host attempted: " + hostname + ". Database: " + DBname);
			return;
		}
		System.out.println("Connetion established to: " + hostname + ". Database: " + 
				DBname);
	}
	// parseToDB constructor for connections made with the hostname AND database
	// name AND port number supplied.
	public parseToDB(String hostname, String DBname, int port)
	{
		try {
			m = new Mongo(hostname, port);
			this.hostname = hostname;
			this.DBname = DBname;
			db = m.getDB(DBname);
			this.port = -1;
		} catch (UnknownHostException e) {
			System.out.println("UnknownHostException error encountered. " +
					"Host attempted: " + hostname + " port: " + port + 
					". Database: " + DBname);
			return;
		} catch (MongoException e) {
			System.out.println("MongoException error encountered. " +
					"Host attempted: " + hostname + " port: " + port + 
					". Database: " + DBname);
			return;
		}
		System.out.println("Connetion established to: " + hostname + " port: " + port + 
				". Database: " + DBname);
	}

	// Creates the indexes for the collections
	public void ensureIndexes() 
	{
		DBCollection coll = db.getCollection("job_events");
		BasicDBObject job_event_keys = new BasicDBObject();
		job_event_keys.put("time", 1);
		job_event_keys.put("job_id", 1);
		coll.ensureIndex(job_event_keys);

		coll = db.getCollection("machine_attributes");
		BasicDBObject machine_attr_keys = new BasicDBObject();
		machine_attr_keys.put("attr.name", 1);
		coll.ensureIndex(machine_attr_keys);

		coll = db.getCollection("machine_events");
		BasicDBObject machine_event_keys = new BasicDBObject();
		machine_event_keys.put("time", 1);
		machine_event_keys.put("machine_id", 1);
		coll.ensureIndex(machine_event_keys);

		coll = db.getCollection("task_constraints");
		BasicDBObject task_const_keys = new BasicDBObject();
		task_const_keys.put("job_id", 1);
		task_const_keys.put("task_index", 1);
		coll.ensureIndex(task_const_keys);

		coll = db.getCollection("task_events");
		BasicDBObject task_event_keys = new BasicDBObject();
		task_event_keys.put("job_id", 1);
		task_event_keys.put("task_index", 1);
		coll.ensureIndex(task_event_keys);

		coll = db.getCollection("task_usage");
		BasicDBObject task_usage_keys = new BasicDBObject();
		task_usage_keys.put("job_id", 1);
		task_usage_keys.put("task_index", 1);
		coll.ensureIndex(task_usage_keys);
	}



	public int getPort() {
		return port;
	}


	public int jobEvents(BufferedReader input){
		int lineNumber = 0;
		DBCollection coll = db.getCollection("job_events");
		try {
			line = input.readLine();

			while(line != null)
			{
				tokens = line.split(delims, -1);	

				try{
				BasicDBObject jobEvents_obj = new BasicDBObject();
				jobEvents_obj.put("time", tokens[0]);
				if((tokens[1]).equals(""))
					jobEvents_obj.put("missing_info", -1);
				else
					jobEvents_obj.put("missing_info", tokens[1]);
				jobEvents_obj.put("job_id", tokens[2]);
				jobEvents_obj.put("event_type", tokens[3]);
				//jobEvents_obj.put("user", tokens[4]);
				jobEvents_obj.put("class", tokens[5]);
				//jobEvents_obj.put("job_name", tokens[6]);
				jobEvents_obj.put("logical_name", tokens[7]);

				coll.insert(jobEvents_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}
	public int machineattr(BufferedReader input){
		int lineNumber = 0;
		DBCollection coll = db.getCollection("machine_attributes");
		try {
			line = input.readLine();
			while(line != null)
			{			
				tokens = line.split(delims, -1);	

				try{
				BasicDBObject machineAttr_obj = new BasicDBObject();
				machineAttr_obj.put("time", tokens[0]);
				machineAttr_obj.put("machine_id", tokens[1]);

				BasicDBObject attr = new BasicDBObject();
				attr.put("name", tokens[2]);
				attr.put("value", tokens[3]);
				attr.put("deleted", tokens[4]);
				machineAttr_obj.put("attr", attr);
				coll.insert(machineAttr_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}
	public int machineEvents(BufferedReader input){
		int lineNumber = 0;
		DBCollection coll = db.getCollection("machine_events");
		try {
			line = input.readLine();
			while(line != null)
			{
				tokens = line.split(delims, -1);	
				try{

				BasicDBObject machineEvents_obj = new BasicDBObject();
				machineEvents_obj.put("time", tokens[0]);
				machineEvents_obj.put("machine_id", tokens[1]);
				machineEvents_obj.put("event_type", tokens[2]);
				//machineEvents_obj.put("platform_id", tokens[3]);

				BasicDBObject capacity = new BasicDBObject();
				capacity.put("cpu", tokens[4]);
				capacity.put("mem", tokens[5]);
				machineEvents_obj.put("capacity", capacity);
				coll.insert(machineEvents_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}
	public int taskConstraints(BufferedReader input)
	{ 
		int lineNumber = 0;
		DBCollection coll = db.getCollection("task_constraints");
		try {
			line = input.readLine();
			while(line != null)
			{
				tokens = line.split(delims, -1);	
				try{
				BasicDBObject task_obj = new BasicDBObject();
				task_obj.put("time", tokens[0]);
				task_obj.put("job_id", tokens[1]);
				task_obj.put("task_index", tokens[2]);
				task_obj.put("comp_op", tokens[5]);

				BasicDBObject attr = new BasicDBObject();
				attr.put("name", tokens[3]);
				attr.put("value", tokens[4]);
				task_obj.put("attr", attr);
				coll.insert(task_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}	
	public int taskEvents(BufferedReader input){
		int lineNumber = 0;
		DBCollection coll = db.getCollection("task_events");
		try {
			line = input.readLine();
			while(line != null)
			{
				tokens = line.split(delims, -1);	
				try {
				BasicDBObject taskEvents_obj = new BasicDBObject();
				taskEvents_obj.put("time", tokens[0]);
				if((tokens[1]).equals(""))
					taskEvents_obj.put("missing_info", -1);
				else
					taskEvents_obj.put("missing_info", tokens[1]);		        
				taskEvents_obj.put("job_id", tokens[2]);
				taskEvents_obj.put("task_index", tokens[3]);
				taskEvents_obj.put("machine_id", tokens[4]);
				taskEvents_obj.put("event_type", tokens[5]);
				//taskEvents_obj.put("user", tokens[6]);
				taskEvents_obj.put("class", tokens[7]);
				taskEvents_obj.put("priority", tokens[8]);


				BasicDBObject resource_request_obj = new BasicDBObject();
				resource_request_obj.put("cpu", tokens[9]);
				resource_request_obj.put("ram", tokens[10]);
				resource_request_obj.put("disk", tokens[11]);

				taskEvents_obj.put("machine_constraint", tokens[12]);

				taskEvents_obj.put("resource_req", resource_request_obj);
				coll.insert(taskEvents_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}
	public int taskUsage(BufferedReader input){
		int lineNumber = 0;
		DBCollection coll = db.getCollection("task_usage");
		try {
			line = input.readLine();
			while(line != null)
			{
				tokens = line.split(delims, -1);	
				try {
				BasicDBObject taskUsage_obj = new BasicDBObject();
				taskUsage_obj.put("start", tokens[0]);
				taskUsage_obj.put("end", tokens[1]);
				taskUsage_obj.put("job_id", tokens[2]);
				taskUsage_obj.put("task_index", tokens[3]);
				taskUsage_obj.put("machine_id", tokens[4]);

				BasicDBObject memory_usage_obj = new BasicDBObject();
				memory_usage_obj.put("canonical", tokens[6]);
				memory_usage_obj.put("assigned", tokens[7]);
				memory_usage_obj.put("max", tokens[10]);
				memory_usage_obj.put("disk_usg", tokens[12]);
				taskUsage_obj.put("mem_usg", memory_usage_obj);

				BasicDBObject page_cache_obj = new BasicDBObject();
				page_cache_obj.put("unmapped", tokens[8]);
				page_cache_obj.put("total", tokens[9]);
				taskUsage_obj.put("page_cache", page_cache_obj);

				BasicDBObject cpu_obj = new BasicDBObject();
				cpu_obj.put("rate", tokens[5]);
				cpu_obj.put("max_rate", tokens[13]);
				taskUsage_obj.put("cpu", cpu_obj);

				BasicDBObject disk_io_obj = new BasicDBObject();
				disk_io_obj.put("rate", tokens[11]);
				disk_io_obj.put("max_rate", tokens[14]);
				taskUsage_obj.put("disk_io", disk_io_obj);

				taskUsage_obj.put("cpi", tokens[15]);
				taskUsage_obj.put("mapi", tokens[16]);
				taskUsage_obj.put("sample", tokens[17]);
				taskUsage_obj.put("agg_type", tokens[18]);

				coll.insert(taskUsage_obj);
				}
				catch (Exception e){
					System.out.println("Could not parse line " + lineNumber);
				}
				lineNumber++;
				line = input.readLine();
			}
		} catch (IOException e) {
			System.out.println("Parsing failed, logged.");
			return FAILED;
		} 
		return SUCCESS;
	}

}
